﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.ComponentModel;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Threading;


namespace MouseReplay
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    class MousePos
    {
        private Double x = 0;
        private Double y = 0;
        public Double X
        {
            get { return x; }
        }

        public Double Y
        {
            get { return y; }
        }

        public MousePos(Double x, Double y)
        {
            this.x = x;
            this.y = y;
        }
    }
    public partial class Window1 : Window
    {
        List<MousePos> movimentos = new List<MousePos>();
        Boolean mouseOnCanvas = false;
        Boolean gravando = false;
        Canvas temp_canvas = new Canvas();
        Int32 contador = 3;

        System.Windows.Forms.Timer tempo = new System.Windows.Forms.Timer();

        public Window1()
        {
            InitializeComponent();
            temp_canvas.Background = Brushes.Black;
            temp_canvas.MouseEnter += new MouseEventHandler(temp_canvas_MouseEnter);
            temp_canvas.MouseLeave += new MouseEventHandler(temp_canvas_MouseLeave);
            scrollViewer1.Content = temp_canvas;
            tempo.Interval = 1000;
            tempo.Tick += new EventHandler(tempo_Tick);
        }

        void tempo_Tick(object sender, EventArgs e)
        {

            if (contador > 0)
            {
                statusLabel.Content = contador.ToString();
                contador--;
            }
            else
            {
                statusLabel.Content = "";
            }
        }


        void temp_canvas_MouseLeave(object sender, MouseEventArgs e)
        {
            mouseOnCanvas = false;
        }

        void temp_canvas_MouseEnter(object sender, MouseEventArgs e)
        {
            mouseOnCanvas = true;
        }

        void Window1_MouseMove(object sender, MouseEventArgs e)
        {
            if (gravando && mouseOnCanvas && contador <= 0)
            {
                Double X = e.GetPosition(temp_canvas).X;
                Double Y = e.GetPosition(temp_canvas).Y;
                movimentos.Add(new MousePos(X, Y));
            }
        }

        private void Record_Bt_Click(object sender, RoutedEventArgs e)
        {
            contador = 3;
            movimentos.Clear();
            temp_canvas.Children.Clear();
            gravando = true;
            tempo.Start();
        }

        private void Stop_Bt_Click(object sender, RoutedEventArgs e)
        {
            gravando = false;
        }

        private void Replay_Bt_Click(object sender, RoutedEventArgs e)
        {
            replay();
        }

        public void replay()
        {
            Int32 n = 0;
            temp_canvas.Children.Clear();
            for (int i = 0; i < movimentos.Count; i++)
            {
                n++;
                try
                {
                    Line l = new Line();
                    l.X1 = movimentos[i].X;
                    l.Y1 = movimentos[i].Y;
                    l.X2 = movimentos[i + 1].X;
                    l.Y2 = movimentos[i + 1].Y;
                    l.Stroke = GetRandomBrush();
                    l.StrokeThickness = 2f;
                    temp_canvas.Children.Add(l);
                    if (n >= 10)
                    {
                        Label label = new Label();
                        label.Foreground = Brushes.White;
                        label.Content = i.ToString();
                        label.Margin = new Thickness(l.X1, l.Y1, 0, 0);
                        temp_canvas.Children.Add(label);
                        n = 0;
                    }
                }
                catch { }
            }
        }

        private System.Windows.Media.Brush GetRandomBrush()
        {
            Random random = new Random();
            SolidColorBrush brush = new SolidColorBrush();
            double r, g, b;
            double lightness = random.NextDouble() * 0.5 + 0.4;
            double hue = random.NextDouble() * 360.0;
            double saturation = random.NextDouble() * 0.8 + 0.2;
            ColorTransform.HSLtoRGB(hue, saturation, lightness, out r, out g, out b);
            brush.Color = System.Windows.Media.Color.FromRgb((byte)(r * 255.0), (byte)(g * 255.0), (byte)(b * 255.0));
            return brush;
        }
    }
    #region Static Class
    public static class ColorTransform
    {
        public static void HSLtoRGB(double hue, double saturation, double luminance, out double red, out double green, out double blue)
        {
            double q;
            double p;
            if (luminance < 0.5)
            {
                q = luminance * (1.0 + saturation);
            }
            else
            {
                q = luminance + saturation - (luminance * saturation);
            }
            p = 2 * luminance - q;
            double hk = hue / 360.0;
            double tr = hk + 1.0 / 3.0;
            double tg = hk;
            double tb = hk - 1.0 / 3.0;
            tr = Normalize(tr);
            tg = Normalize(tg);
            tb = Normalize(tb);
            red = ComputeColor(q, p, tr);
            green = ComputeColor(q, p, tg);
            blue = ComputeColor(q, p, tb);
        }

        private static double ComputeColor(double q, double p, double tc)
        {
            if (tc < 1.0 / 6.0)
            {
                return p + ((q - p) * 6.0 * tc);
            }
            if (tc < 0.5)
            {
                return q;
            }
            if (tc < 2.0 / 3.0)
            {
                return p + ((q - p) * 6.0 * (2.0 / 3.0 - tc));
            }
            return p;
        }

        private static double Normalize(double tr)
        {
            if (tr < 0)
            {
                return tr + 1.0;
            }
            if (tr > 1.0)
            {
                return tr - 1.0;
            }
            return tr;
        }
    }
    #endregion

}
